import * as echarts from 'echarts/core';
import { CanvasRenderer } from 'echarts/renderers';
import {
  TitleComponent,
  LegendComponent,
  TooltipComponent,
  GridComponent,
  DatasetComponent,
  TransformComponent,
  DataZoomComponent,
} from 'echarts/components';
import { LabelLayout, UniversalTransition } from 'echarts/features';
import { BarChart, GaugeChart, LineChart, PictorialBarChart, PieChart } from 'echarts/charts';
import { merge, forEach } from 'lodash-es';

const optionsModules = type => {
  if (process.env.NODE_ENV === 'development') {
    return require(`@/components/chart/options/${type}.js`);
  } else {
    // 使用 import 实现生产环境的路由懒加载
    return import(`@/components/chart/options/${type}.js`);
  }
};
class ChartsResize {
  #charts = new Set(); // 缓存已经创建的图表实例
  #timeId = null;
  resizeObserver = null;
  constructor() {
    window.addEventListener('resize', this.handleResize.bind(this)); // 视口变化时调整图表
    this.resizeObserver = new ResizeObserver(() => this.handleResize());
  }
  getCharts() {
    return [...this.#charts];
  }
  handleResize() {
    clearTimeout(this.#timeId);
    this.#timeId = setTimeout(() => {
      this.#charts.forEach(chart => {
        chart.resize();
      });
    }, 100);
  }
  add(chart, el) {
    this.#charts.add(chart);
    this.resizeObserver.observe(el);
  }
  remove(chart) {
    this.#charts.delete(chart);
  }
  removeListener() {
    window.removeEventListener('resize', this.handleResize);
    this.resizeObserver.disconnect();
  }
}

export const chartsResize = new ChartsResize();

export const useCharts = ({ type, el }) => {
  echarts.use([
    BarChart,
    GaugeChart,
    LineChart,
    PictorialBarChart,
    PieChart,
    TitleComponent,
    LegendComponent,
    TooltipComponent,
    GridComponent,
    DatasetComponent,
    TransformComponent,
    DataZoomComponent,
    LabelLayout,
    UniversalTransition,
    CanvasRenderer,
  ]);
  let initComplete = false;
  const charts = shallowRef();

  let options;
  const getOptions = async () => {
    // 加type判断，是为了sankey chart
    const { default: defaultOption } = type.value ? await optionsModules(type.value) : { default: () => null };
    return defaultOption();
  };

  const assembleDataToOption = async option => {
    options = await getOptions();
    return merge({}, options, option);
  };

  const setOptions = async (option, opts = true) => {
    const fullOption = await assembleDataToOption(option);
    initComplete && charts.value.setOption(fullOption, opts);
  };

  const initChart = () => {
    if (el.value.clientWidth && el.value.clientHeight) {
      charts.value = echarts.init(el.value);
      chartsResize.add(charts.value, el.value); // 将图表实例添加到缓存中
      initEvent(); // 添加事件支持
      initComplete = true;
    }
  };

  /**
   * 初始化事件
   */
  const attrs = useAttrs();
  const initEvent = () => {
    forEach(Object.keys(attrs), attrKey => {
      if (/^on/.test(attrKey)) {
        const cb = attrs[attrKey];
        attrKey = attrKey.replace(/^on(Chart)?/, '');
        attrKey = `${attrKey[0].toLocaleLowerCase()}${attrKey.substring(1)}`;
        typeof cb === 'function' && charts.value?.on(attrKey, cb);
      }
    });
  };
  onBeforeUnmount(() => {
    chartsResize.remove(charts.value); // 移除缓存
    chartsResize.removeListener(); // 移除resize监听
  });

  return {
    echarts,
    charts,
    setOptions,
    initChart,
    initEvent,
  };
};

// export const chartsOptions = option => shallowReactive(option);
